package com.baidu.process.scheduled;

import com.alibaba.fastjson.JSONObject;
import com.baidu.process.chat.core.web.bean.IMRequestServer;
import com.baidu.process.chat.core.web.bean.eval.EvalResult;
import com.baidu.process.chat.core.web.bean.eval.EvalVO;
import com.baidu.process.chat.core.web.service.IEvaluationService;
import com.baidu.process.config.service.OptAnswerService;
import com.baidu.process.constant.EvalConstant;
import com.baidu.process.constant.OptEventEnum;
import com.baidu.process.imchat.entity.ImResult;
import com.baidu.process.imchat.service.ImChatService;
import com.baidu.process.ngd.service.impl.NGDServiceImpl;
import com.baidu.process.record.bean.DialogueRecord;
import com.baidu.process.record.service.RecordService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.baidu.process.constant.RedisKey.ImSilentNumKey;
import static com.baidu.process.constant.RedisKey.ImTimeKey;

/**
 * @Author:fangyuchao
 * @Description:
 * @Description: 定时查询redis内进线的sessionid时间是否超过规定时长
 * @Date: Create in 16:52 2022/11/7
 */
@Component
public class ImSessionScheduled {

    private static final Logger logger= LoggerFactory.getLogger(ImSessionScheduled.class);
    private static final  String imScheduLock = "imScheduLock";
    @Autowired
    private OptAnswerService optAnswerService;
    @Autowired
    private  IEvaluationService evalResultService;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private ImChatService imChatService;

    @Value("${im.silent.timeout.second}")
    private String imTimeOutSecond ;
    @Autowired
    private RecordService recordService;
    @Scheduled(cron = "${im.timer.cron}")
    public void sendMsgSessionOverTime(){
        try{

        long nowTime = System.currentTimeMillis();
        //设置锁，保证多实例下定时任务只有一个实例在执行
        //获取锁，过期时间10分钟
        boolean isgetLock = redisTemplate.opsForValue().setIfAbsent(imScheduLock,"ok",10,TimeUnit.MINUTES);
        if (isgetLock){
            DialogueRecord dialogueRecord = new DialogueRecord();
            //生成queryId
            dialogueRecord.setQueryId(UUID.randomUUID().toString());
            dialogueRecord.setSource("scheduled");
            //给im发送的信息列表
            List<String> imMsgList = new ArrayList<>();
            //获取redis内所有session的时间 , ImTimeKey+sessionid   :  imRequestServerSet
            Set<String> timeSet= redisTemplate.keys(ImTimeKey+"*");
            for (String sessionKey :  timeSet){
                String imRequestServerStr= redisTemplate.opsForValue().get(sessionKey);
                if (StringUtils.isEmpty(imRequestServerStr)){
                    continue;
                }
                IMRequestServer imRequestServer = JSONObject.parseObject(imRequestServerStr,IMRequestServer.class);
                String session_1 = sessionKey.replaceAll(ImTimeKey,"");
                if (StringUtils.isEmpty(session_1)){
                    continue;
                }
                System.out.println("处理session："+session_1);
                String time_1 = imRequestServer.getStartTime();
                String channel = imRequestServer.getChannel();
                //判断时间差是否超过预设时间
                boolean isOverTime = nowTime - Long.parseLong(time_1)>=Long.parseLong(imTimeOutSecond)*1000;
                if (!isOverTime){
                    continue;
                }
                //判断为静默超时
                //获取当前静默超时次数
                String numStr = redisTemplate.opsForValue().get(ImSilentNumKey+session_1);

                int num = StringUtils.isEmpty(numStr)?0:Integer.parseInt(numStr);
                //之前已经超时过一次,发送第二次静默超时话术
                //向im发送消息
                List<Map<String,Object>> msgBody = new ArrayList<>();
                Map<String,Object> map = new HashMap<>();
                map.put("msgType","TIMTextElem");
                Map<String,String> textMap = new HashMap<>();
                textMap.put("text",optAnswerService.getAnswerByEvent(OptEventEnum.silentFirst.name()));
                if (num>=1){

                    //调用满意度接口获取满意度链接
                    EvalVO evalVO = new EvalVO();
                    evalVO.setChannel(channel);
                    evalVO.setSessionId(session_1);
                    EvalResult evalResult = evalResultService.pushEval(evalVO);
                    //通过渠道推送不同链接格式
                    System.out.println("渠道："+channel);
                    //渠道0推送
                    if (EvalConstant.CHANNEL_WX.equals(channel)){

                        map.put("msgType","TIMTextElem");
                        String evalUrl = JSONObject.parseObject(evalResult.getJsonString()).get("url").toString();
                        //拼接上满意度
                        textMap.put("text",optAnswerService.getAnswerByEvent(OptEventEnum.silentSecond.name())+"\n"+"<a href='"+evalUrl+"'>客户满意度调研</a>");
                    }else{
                        map.put("msgType","TIMCustomElem");
                        String evalJson = evalResult.getJsonString();
                        //推送满意度
                        textMap.put("desc",evalJson);
                    }
                    map.put("msgContent",textMap);
                    msgBody.add(map);
                    ImResult imResult = imChatService.imChat(imRequestServer,msgBody);
                    imMsgList.add(JSONObject.toJSONString(msgBody));
                    //发完满意度后再提交关闭
                    List<Map<String,Object>> closeMsgBody = new ArrayList<>();
                    Map<String,Object> closeMap = new HashMap<>();
                    Map<String,String> closeTextMap = new HashMap<>();
                    closeTextMap.put("text",optAnswerService.getAnswerByEvent(OptEventEnum.closeText.name()));
                    closeMap.put("msgContent",closeTextMap);
                    closeMap.put("msgType","TIMClose");
                    closeMsgBody.add(closeMap);
                    ImResult imCloseResult = imChatService.imChat(imRequestServer,closeMsgBody);
                    imMsgList.add(JSONObject.toJSONString(closeMsgBody));
                    dialogueRecord.setImchatData(JSONObject.toJSONString(imMsgList));
                    recordService.saveAsyncRecord(dialogueRecord,imRequestServer,null,null);
                    redisTemplate.delete(sessionKey);
                    redisTemplate.delete(ImSilentNumKey+session_1);
                }else{
                    map.put("msgType","TIMTextElem");
                    map.put("msgContent",textMap);
                    msgBody.add(map);
                    ImResult imResult = imChatService.imChat(imRequestServer,msgBody);
                    imMsgList.add(JSONObject.toJSONString(msgBody));
                    dialogueRecord.setImchatData(JSONObject.toJSONString(imMsgList));
                    recordService.saveAsyncRecord(dialogueRecord,imRequestServer,null,null);
                    //第一次超时，重置session对应的交互时间，
                    imRequestServer.setStartTime(Long.toString(System.currentTimeMillis()));
                    redisTemplate.opsForValue().set(ImTimeKey+session_1,JSONObject.toJSONString(imRequestServer), 20,TimeUnit.MINUTES);
                    redisTemplate.opsForValue().set(ImSilentNumKey+session_1,Integer.toString(num+1),6,TimeUnit.HOURS);
                }
            }
        }

    }catch (Exception e){
            e.printStackTrace();
            logger.error("定时检测任务执行异常!",e);
        }finally {
            //释放锁
            redisTemplate.delete(imScheduLock);
        }
    }
}

